namespace Guia.Elements
{
    using System.Windows.Automation;
    using Guia.Core;
    using Guia.Elements.PatternServants;
    using Guia.Locator;

    /// <summary>
    /// This class representa a TreeViewItem. A <see cref="TreeView"/> and each TreeViewItem can have multiple TreeViewItems.
    /// </summary>
    public class TreeViewItem : AbstractTreeView, IExpandCollapse
    {
        /// <summary>
        /// Represents a helper-servant for the ExpandCollapse-pattern.
        /// </summary>
        private readonly IExpandCollapse expandCollapseServant;

        /// <summary>
        /// Initializes a new instance of the <see cref="TreeViewItem"/> class.
        /// </summary>
        /// <param name="automationElement">
        /// The automation element.
        /// </param>
        public TreeViewItem(AutomationElement automationElement) : base(automationElement)
        {
            this.expandCollapseServant = new ExpandCollapseImpl(this);
        }

        /// <summary>
        /// Gets the default-condition to find a control by its type.
        /// </summary>
        public static SearchCondition ControlTypeCondition
        {
            get { return SearchCondition.ByControlType(ControlType.TreeItem); }
        }

        /// <summary>
        /// Gets the header.
        /// </summary>
        public string Header
        {
            get
            {
                return this.automationElement.Current.Name;
            }
        }

        /// <summary>
        /// Gets or sets a value indicating whether this TreeViewItem is selected or not.
        /// </summary>
        public bool IsSelected
        {
            get
            {
                return this.SelectionItemPattern.Current.IsSelected;
            }

            set
            {
                if (value != this.IsSelected)
                {
                    if (value)
                    {
                        this.Select();
                    }
                    else
                    {
                        this.Unselect();
                    }
                }
            }
        }

        /// <summary>
        /// Gets or sets a value indicating whether this TreeViewItem is expanded or not.
        /// </summary>
        public bool IsExpanded
        {
            get
            {
                return this.expandCollapseServant.IsExpanded;
            }

            set
            {
                this.expandCollapseServant.IsExpanded = value;
            }
        }

        /// <summary>
        /// Gets all direct TreeViewItems of this element.
        /// If the TreeViewItem is not expanded, it will be expanded first.
        /// </summary>
        public override TreeViewItem[] Items
        {
            get
            {
                if (!this.IsExpanded)
                {
                    this.Expand();
                }

                return base.Items;
            }
        }

        /// <summary>
        /// Gets the SelectionItemPattern.
        /// </summary>
        private SelectionItemPattern SelectionItemPattern
        {
            get
            {
                return this.GetPattern<SelectionItemPattern>();
            }
        }

        /// <summary>
        /// Gets the TreeViewItem with the given name (Header value).
        /// If the TreeViewItem is not expanded, it will be expanded first.
        /// </summary>
        /// <param name="itemName">
        /// The name (Header) of the TreeViewItem.
        /// </param>
        /// <returns>
        /// The TreeViewItem with the given name (Header value).
        /// </returns>
        public override TreeViewItem GetItem(string itemName)
        {
            if (!this.IsExpanded)
            {
                this.Expand();
            }

            return base.GetItem(itemName);
        }

        /// <summary>
        /// Selects this TreeViewItem.
        /// </summary>
        /// <exception cref="OperationNotSupportedException">
        /// </exception>
        public void Select()
        {
            if (!this.IsEnabled)
            {
                throw new OperationNotSupportedException("The element is disabled");
            }

            this.SelectionItemPattern.Select();
        }

        /// <summary>
        /// Unselects this TreeViewItem.
        /// </summary>
        public void Unselect()
        {
            this.SelectionItemPattern.RemoveFromSelection();
        }

        /// <summary>
        /// Expands this TreeViewItem.
        /// </summary>
        /// <exception cref="OperationNotSupportedException">
        /// </exception>
        public void Expand()
        {
            this.expandCollapseServant.Expand();
        }

        /// <summary>
        /// Collapses this TreeViewItem.
        /// </summary>
        /// <exception cref="OperationNotSupportedException">
        /// </exception>
        public void Collapse()
        {
            this.expandCollapseServant.Collapse();
        }
    }
}